import logging
import signal
import threading
import pathlib

from p2p import ecies
from eth_keys import keys

from .utils import sig
from ..config import NULL_MAX
from . import add_boostrap_nodes, null_delta_check, process_pending_pings, process_pending_neighbors
from ..protocol import Connection
from ..data_management.redis import redis_init


def run(is_quiet, logs=True, key_file="crawleth_prv.key"):
    redis_db = redis_init()

    crawleth_keyfile = pathlib.Path(key_file)
    if crawleth_keyfile.exists ():
        with open(crawleth_keyfile, 'rb') as f:
            crawleth_key = keys.PrivateKey(f.read())
    else:
        crawleth_key = ecies.generate_privkey()
        with open(crawleth_keyfile, 'wb') as f:
            f.write(crawleth_key.to_bytes()) 
    
    conn = Connection(logger=logging.getLogger(),
                      private_key=crawleth_key,
                      redis_db=redis_db)
    conn.open()

    add_boostrap_nodes(redis_db)

    delta_thread = threading.Thread(target=null_delta_check, args=(conn, NULL_MAX, is_quiet),
                                    daemon=True)
    ping_thread = threading.Thread(target=process_pending_pings, args=(conn,), daemon=True)
    neighbors_thread = threading.Thread(target=process_pending_neighbors, args=(conn,), daemon=True)

    original_sigint_handler = signal.getsignal(signal.SIGINT)
    signal.signal(signal.SIGINT, sig)

    delta_thread.start()
    ping_thread.start()
    neighbors_thread.start()

    # wait until crawling finishes
    # matplotlib doesn't like to be launched outside of main thread
    ping_thread.join()
    neighbors_thread.join()
    delta_thread.join()

    signal.signal(signal.SIGINT, original_sigint_handler)
